package Bots;


import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
import cz.cuni.amis.pogamut.base.utils.guice.AgentScoped;
import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004BotModuleController;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.AutoTraceRay;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Item;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

@AgentScoped
public class Bots extends UT2004BotModuleController<UT2004Bot> {
    /////////////////////////////////////////////////	
    public int numState;
    public int numAction;
    public int trial;
    public int TF_num;
    public int step;
    public int TF_num1;
    public int step1;
    public int fitness1;
    public int fitness2;
    public double KD;
    public double ddistance = 0;
    public Location loc = null;

    public double rewards;
    public double rewards1;

    public double Qbest;
    public double Si;
    public double EI;
    public double Sc;

    public int bask = 1000;
    public int bgive = 1000;

    public int action0 = 0;
    public int action1 = 0;
    public int action2 = 0;
    public int action3 = 0;

    public int a0 = 0;
    public int a1 = 0;
    public int a2 = 0;
    public int a3 = 0;

    public double[] stat;//健康，受损，敌人发现，足够弹药
    public double[] CurrentStat;
    public double[] CurrentStat1;
    public double[] NextStat;

    public int action;
    public int prior_action;
    public boolean[] vact;
    public double r;
    public boolean end;

    public boolean start;
    public boolean stop;


    public int capacity = 99999;

    //public Buffer [] buff;
    public List<Buffer> buff = new ArrayList<Buffer>();


    public int kill = 0;
    public int die = 0;
    public int kill1 = 0;
    public int die1 = 0;

    public boolean flag = false;
    public boolean isdead;
    public int[] act;
    public IWorldEventListener<?> botDamagedListener;
    public IWorldEventListener<?> PlayerDamagedListener;
    public IWorldEventListener<?> PlayerKilledListener;
    public IWorldEventListener<?> BotKilledListener;

    public Bots(int num_stat, int num_act) {
        this(0, num_stat, num_act, false, "Bots" + 0);
    }

    public Bots(int agent_num, int num_stat, int num_act) {
        this(agent_num, num_stat, num_act, false, "Bots" + agent_num);
    }

    public Bots(int agent_num, int num_stat, int num_act, boolean rw) {
        this(agent_num, num_stat, num_act, rw, "Bots" + agent_num);
    }

    public Bots(int agent_num, int num_stat, int num_act, boolean rw, String name) {
        this.numState = num_stat;
        this.numAction = num_act;
        Qbest = 0;
        fitness1 = 0;
        fitness2 = 0;
        KD = 0;
        stat = new double[numState];
        CurrentStat = new double[numState];
        CurrentStat1 = new double[numState];
        NextStat = new double[numState];

        vact = new boolean[numAction];

        //buff=new Buffer[capacity];

        if (!rw) {
            buff.add(new Buffer(numState, numAction));
        } else {
            try {
                readfile(agent_num, name);
            } catch (Exception e) {
                buff.add(new Buffer(numState, numAction));

            }
        }

    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////
    public AutoTraceRay left90, front, right90, left45, right45, behind, bright45, bleft45;

    public boolean first = true;

    public boolean raysInitialized = false;

    public boolean sensorLeft45 = false;
    public boolean sensorRight45 = false;
    public boolean sensorLeft90 = false;
    public boolean sensorRight90 = false;
    public boolean sensorFront = false;
    public boolean sensorBLeft45 = false;
    public boolean sensorBRight45 = false;
    public boolean sensorBehind = false;
    public boolean moving = false;
    public boolean sensor = false;


    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //何时做判断
    public Item item;
    public Item medic_item;
    public Player enemy;
    public List<Item> itemsToRunAround;
    public List<Item> interesting = new ArrayList<>();

    public boolean playersToRunAround;
    public boolean shooting;
    public boolean runningToPlayer;

    public double hitdamage = 0.0;
    public double getdamage = 0.0;


    public double lastdamage;
    public double lastheal = 1.0;
    public double lasthitdamage = 0.0;

    public double distance = 1;
    public int decentDistance = 1;

    public void reset() {
        item = null;
        medic_item = null;
        enemy = null;
        itemsToRunAround = null;
        playersToRunAround = false;
        shooting = false;
        runningToPlayer = false;
        stop = false;
        flag = true;
        Re();

    }

    public void Re() {
        for (int i = 0; i < numState / 2; i++) {
            stat[i * 2] = 1.0;
            stat[i * 2 + 1] = 0.0;
        }
    }

    public double p;
    public double w;


    public void readfile(int agent_num, String name) throws IOException {
        String path = "e:/" + name + agent_num + ".txt";
        FileInputStream in = new FileInputStream(path);
        DataInputStream din = new DataInputStream(in);
        int buff_num = din.readInt();

        for (int j = 0; j < buff_num; j++) {
            Buffer b = new Buffer(numState, numAction);
            ;
            buff.add(new Buffer(numState, numAction));
            for (int i = 0; i < numState; i++) {
                CurrentStat[i] = din.readDouble();
            }
            action = din.readInt();
            r = din.readDouble();
            for (int i = 0; i < numState; i++) {
                NextStat[i] = din.readDouble();
            }
            end = din.readBoolean();
            b.Replay_Buffer(CurrentStat, action, r, NextStat, end);
            buff.add(b);

        }

        din.close();
        in.close();

    }

    public void writefile(int agent_num, String name) throws Exception {
        String path = "e:/" + name + agent_num + ".txt";
        FileOutputStream out = new FileOutputStream(path);
        DataOutputStream dout = new DataOutputStream(out);
        dout.writeInt(buff.size());
        for (int j = 0; j < buff.size(); j++) {
            for (int i = 0; i < numState; i++) {
                dout.writeDouble(buff.get(j).stat[i]);
            }
            dout.writeInt(buff.get(j).action);
            dout.writeDouble(buff.get(j).r);
            for (int i = 0; i < numState; i++) {
                dout.writeDouble(buff.get(j).next_stat[i]);
            }
            dout.writeBoolean(buff.get(j).end);
        }
        dout.close();
        out.close();
    }


    public void observe() {
    }

    public void DoAction(int action) {
    }
}
